package com.tim.framework.page;

import com.sun.rowset.CachedRowSetImpl;

import javax.sql.rowset.CachedRowSet;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 
 * @author Tim.
 */
public class JdbcPage implements Page {
	private CachedRowSet elements;
	private int pageSize;
	private int pageNumber;
	private int totalElements = 0;

	/**
	 * 构建JdbcPage对象，完成JDBC的ResultSet分页处理
	 * 
	 * @param rs
	 *            ResultSet对象，ResultSet必须是可滚动的数据集，可以通过以下的Statement执行查询。
	 *            Statement stmt = conn.createStatement(
	 *            ResultSet.TYPE_SCROLL_INSENSITIVE,
	 *            ResultSet.CONCUR_READ_ONLY);
	 * @param pageNumber
	 *            当前页编码，从1开始，如果传的值为Integer.MAX_VALUE表示获取最后一页。
	 *            如果你不知道最后一页编码，传Integer.MAX_VALUE即可。如果当前页超过总页数，也表示最后一页。
	 *            这两种情况将重新更改当前页的页码，为最后一页编码。
	 * @param pageSize
	 *            每一页显示的条目数
	 */
	public JdbcPage(ResultSet rs, int pageNumber, int pageSize) {
		this.pageNumber = pageNumber;
		this.pageSize = pageSize;
		try {
			// get the total elements number
			rs.last();
			totalElements = rs.getRow();
			if (this.pageNumber == Integer.MAX_VALUE
					|| this.pageNumber > getLastPageNumber()) {
				this.pageNumber = getLastPageNumber();
			}
			elements = new CachedRowSetImpl();
			elements.setMaxRows(this.pageSize);
			elements.setPageSize(this.pageSize);
			elements.populate(rs, (this.pageNumber - 1) * this.pageSize);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public boolean isFirstPage() {
		return getThisPageNumber() == 1;
	}

	public boolean isLastPage() {
		return getThisPageNumber() >= getLastPageNumber();
	}

	public boolean hasNextPage() {
		return getLastPageNumber() > getThisPageNumber();
	}

	public boolean hasPreviousPage() {
		return getThisPageNumber() > 1;
	}

	public int getLastPageNumber() {
		return totalElements % this.pageSize == 0 ? totalElements
				/ this.pageSize : totalElements / this.pageSize + 1;
	}

	/**
	 * 返回RowSet类型数据
	 * 
	 * @return RowSet数据源
	 */
	public Object getThisPageElements() {
		return elements;
	}

	public int getTotalNumberOfElements() {
		return totalElements;
	}

	public int getThisPageFirstElementNumber() {
		return (getThisPageNumber() - 1) * getPageSize() + 1;
	}

	public int getThisPageLastElementNumber() {
		int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
		return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements()
				: fullPage;
	}

	public int getNextPageNumber() {
		return getThisPageNumber() + 1;
	}

	public int getPreviousPageNumber() {
		return getThisPageNumber() - 1;
	}

	public int getPageSize() {
		return pageSize;
	}

	public int getThisPageNumber() {
		return pageNumber;
	}
}
